package com.alex.wechat.mp.config;

import org.apache.commons.lang3.StringUtils;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.core.util.ContextHolderUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alex.wechat.mp.account.entity.WxAccountEntity;
import com.alex.wechat.mp.account.service.WxAccountServiceI;
import com.alex.wechat.mp.fans.entity.WxFansEntity;
import com.alex.wechat.mp.fans.service.WxFansServiceI;

import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;

/**
 * 当前公众号上下文。
 * 
 * <br>
 * 所有与微信相关的上下文，都在这里初始化。
 * 
 * @author Debenson
 * @since 0.1
 */
public class WxContext {
  static final Logger logger = LoggerFactory.getLogger(WxContext.class);

  private static final String KEY_WX_ORIGINAL_ID = "__WX_ORIGINAL_ID__";
  private static final String KEY_WX_APP_ID = "__WX_APP_ID__";
  private static final String KEY_WX_OPEN_ID = "__WX_OPEN_ID__";
  private static WxSessionManager sessionMgr;

  /**
   * 会员session管理者。
   * 
   * @return
   */
  public static synchronized WxSessionManager getWxSessionMgr() {
    if (sessionMgr == null) {
      sessionMgr = new StandardSessionManager();
    }
    return sessionMgr;
  }

  /**
   * 设置微信公众号原始Id.
   * 
   * @param originalId
   */
  public static void setOriginalId(String originalId) {
    ContextHolderUtils.getSession().setAttribute(KEY_WX_ORIGINAL_ID, originalId);
  }

  /**
   * 设置微信Appid
   * 
   * @param appId
   */
  public static void setAppId(String appId) {
    ContextHolderUtils.getSession().setAttribute(KEY_WX_APP_ID, appId);
  }

  /**
   * 设置当前微信粉丝号。
   * 
   * @param openId
   */
  public static void setOpenId(String openId) {
    ContextHolderUtils.getSession().setAttribute(KEY_WX_OPEN_ID, openId);
  }

  /**
   * 取得当前会话微信公众号原始id。只有设置
   * {@link #setOriginalId(String)}或设置了{@link #setOpenId(String)}或设置了{@link #setAppId(String)}才能取得值，否则返回null。
   * 
   * @return
   */
  public static String getOriginalId() {
    WxAccountEntity account = getWxAccount();
    if (account == null) {
      return null;
    } else {
      return account.getOriginalId();
    }
  }

  /**
   * 取得微信Appid
   * 
   * @return
   */
  public static String getAppId() {
    WxAccountEntity account = getWxAccount();
    if (account == null) {
      return null;
    } else {
      return account.getAppid();
    }
  }

  /**
   * 取得当前会话微信粉丝号。 <br>
   * 注意这个值只有运行时才能取得，而且只有当前线程有效。
   * 
   * @return
   */
  public static String getOpenId() {
    return (String) ContextHolderUtils.getSession().getAttribute(KEY_WX_OPEN_ID);
  }

  /**
   * 取得当前会话的微信账户信息。
   * 
   * @return
   */
  public static WxAccountEntity getWxAccount() {
    WxAccountServiceI wxAccountService = ApplicationContextUtil.getBean(WxAccountServiceI.class);

    // 首先通过原始id查找
    String originalId = (String) ContextHolderUtils.getSession().getAttribute(KEY_WX_ORIGINAL_ID);
    if (StringUtils.isNotBlank(originalId)) {
      return wxAccountService.getAccountByOriginalId(originalId);
    }

    // 再通过Appid查找
    String appId = (String) ContextHolderUtils.getSession().getAttribute(KEY_WX_APP_ID);
    if (StringUtils.isNotBlank(appId)) {
      return wxAccountService.getAccountByAppId(appId);
    }

    // 再通过openId查找
    String openId = (String) ContextHolderUtils.getSession().getAttribute(KEY_WX_OPEN_ID);
    if (StringUtils.isNotBlank(openId)) {
      return wxAccountService.getAccountByOpenId(openId);
    }

    return null;
  }

  /**
   * 是否设置了当前微信公众号。
   *
   * @return
   */
  public static boolean hasWxAccount() {
    return getWxAccount() != null;
  }

  /**
   * 取得当前会话的微信粉丝。
   * 
   * @return 微信粉丝信息，如果没有设置 {@link #setOpenId(String)}将返回null。
   */
  public static WxFansEntity getFans() {
    String openId = getOpenId();
    if (StringUtils.isBlank(openId)) {
      return null;
    }

    WxFansServiceI wxFansService = ApplicationContextUtil.getBean(WxFansServiceI.class);
    return wxFansService.getByOpenId(openId);
  }

}
